package model

import (
	"context"
	"fmt"
	"time"

	"github.com/comfygpt-backend-go/common/database"
)

type (
	componentsModel interface {
		Insert(ctx context.Context, data *Components) error
		FindOne(ctx context.Context, id int64) (*Components, error)
		FindOneByName(ctx context.Context, name string) (*Components, error)
		ComponentList(ctx context.Context, pageSize, pageIndex int) ([]*Components, error)
		Update(ctx context.Context, data *Components) error
		Delete(ctx context.Context, id int64) error
	}

	defaultComponentsModel struct {
		db    *database.GormDao
		cache *database.DcRedisClient
		table string
	}

	Components struct {
		Id          int64     `db:"id" gorm:"column:id"`
		Name        string    `db:"name" gorm:"column:name"`               // 组件名称
		Description string    `db:"description" gorm:"column:description"` // 组件描述
		Category    string    `db:"category"`                              // 组件分类
		Icon        string    `db:"icon"`                                  // 组件图标
		Tags        string    `db:"tags"`                                  // 组件标签
		CreateTime  time.Time `db:"create_time"`
		UpdateTime  time.Time `db:"update_time"`
	}
)

func newComponentsModel(conn *database.GormDao, c *database.DcRedisClient) *defaultComponentsModel {
	return &defaultComponentsModel{
		db:    conn,
		cache: c,
		table: "`components`",
	}
}

func (m *defaultComponentsModel) Delete(ctx context.Context, id int64) error {
	comp := &Components{Id: id}
	err := m.db.Delete(ctx, m.table, comp, false)
	if err != nil {
		return err
	}
	return nil
}

func (m *defaultComponentsModel) FindOne(ctx context.Context, id int64) (*Components, error) {
	component := Components{}
	sql := fmt.Sprintf("SELECT * FROM %s WHERE id = ? LIMIT 1", m.table)
	err := m.db.GetDB().Raw(sql, id).Scan(&component).Error
	if err != nil {
		return nil, err
	}
	return &component, nil
}

func (m *defaultComponentsModel) FindOneByName(ctx context.Context, name string) (*Components, error) {
	component := Components{}
	sql := fmt.Sprintf("SELECT * FROM %s WHERE name = ? LIMIT 1", m.table)
	err := m.db.GetDB().Raw(sql, name).Scan(&component).Error
	if err != nil {
		return nil, err
	}
	return &component, nil
}

// ComponentList 获取组件列表
func (m *defaultComponentsModel) ComponentList(ctx context.Context, pageSize, pageIndex int) ([]*Components, error) {
	var components []*Components
	err := m.db.FindByPage(ctx, m.tableName(), pageSize, pageIndex, &components, nil, nil)
	if err != nil {
		return nil, err
	}
	return components, nil
}

func (m *defaultComponentsModel) Insert(ctx context.Context, data *Components) error {
	err := m.db.Create(ctx, m.table, data)
	if err != nil {
		return err
	}
	return nil
}

func (m *defaultComponentsModel) Update(ctx context.Context, newData *Components) error {
	err := m.db.Update(ctx, m.table, uint(newData.Id), newData)
	if err != nil {
		return err
	}
	return nil
}

func (m *defaultComponentsModel) tableName() string {
	return m.table
}
